﻿#pragma once

#include "engine_interface.h"
#include "RTCDefine.h"
#include <QObject>

using namespace ding::rtc;

class AliRtcEventHandler : public ding::rtc::RtcEngineEventListener
{
public:
    AliRtcEventHandler(QObject* parent);
    // 加入频道结果，成功返回0，失败返回错误码
    void OnJoinChannelResult(int result, const char *channel, const char *userId,
                             int elapsed) override;
    void OnLeaveChannelResult(int result, ding::rtc::RtcEngineStats stats) override;
    // void OnChannelRemainingTimeNotify(int remainingTimeInSec) override;
    void OnRemoteUserOnLineNotify(const char* uid, int elapsed) override;
    void OnRemoteUserOffLineNotify(const char* uid, ding::rtc::RtcEngineUserOfflineReason reason) override;
    void OnBye(RtcEngineOnByeType code) override;
    // void OnConnectionStatusChanged(ding::rtc::RtcEngineConnectionStatus status, ding::rtc::RtcEngineConnectionStatusChangeReason reason) override;
    // void OnNetworkQualityChanged(const char* uid, ding::rtc::RtcEngineNetworkQuality upQuality, ding::rtc::RtcEngineNetworkQuality downQuality) override;
    // void OnStatisticsLog(String const& log) override;
    // void OnOccurWarning(int warn, const char* msg) override;
    void OnOccurError(int error, const char* msg) override;
    // void OnStatisticsLevelLog(int level, const String& log) override;
    // void OnQualityReport(const ding::rtc::QualityReport& quality) override;
    //void OnLocalAudioStats(const ding::rtc::LocalAudioStats& localAudioStats) override;
    // void OnLocalVideoStats(const ding::rtc::LocalVideoStats& localVideoStats) override;
    // void OnRemoteAudioStats(const ding::rtc::RemoteAudioStats& remoteAudioStats) override;
    // void OnRemoteVideoStats(const ding::rtc::RemoteVideoStats& remoteVideoStats) override;
    //void OnStats(const ding::rtc::RtcEngineStats& stats) override;
    void OnAudioPublishStateChanged(ding::rtc::RtcEnginePublishState oldState, ding::rtc::RtcEnginePublishState newState, int elapseSinceLastState, const char* channel) override;
    //void OnVideoPublishStateChanged(ding::rtc::RtcEnginePublishState oldState, ding::rtc::RtcEnginePublishState newState, int elapseSinceLastState, const char* channel) override;
    // void OnScreenSharePublishStateChanged(ding::rtc::RtcEnginePublishState oldState, ding::rtc::RtcEnginePublishState newState, int elapseSinceLastState, const char* channel) override;
    void OnRemoteTrackAvailableNotify(const char* uid, ding::rtc::RtcEngineAudioTrack audioTrack, ding::rtc::RtcEngineVideoTrack videoTrack) override;
    // void OnUserAudioMuted(const char* uid, bool isMute) override;
    // void OnUserVideoMuted(const char* uid, bool isMute, ding::rtc::RtcEngineVideoTrack videoTrack) override;
    // void OnUserVideoEnabled(const char* uid, bool enabled) override;
    // void OnUserWillResignActive(const char* uid) override;
    // void OnUserWillBecomeActive(const char* uid) override;
    void OnFirstRemoteVideoFrameDrawn(const char* uid, ding::rtc::RtcEngineVideoTrack videoTrack, int width, int height, int elapsed) override;
    // void OnFirstLocalVideoFrameDrawn(int width, int height, int elapsed) override;
    void OnFirstVideoPacketSend(ding::rtc::RtcEngineVideoTrack videoTrack, int timeCost) override;
    void OnFirstVideoPacketReceived(const char* uid, ding::rtc::RtcEngineVideoTrack videoTrack, int timeCost) override;
    // void OnFirstVideoFrameReceived(const char* uid, ding::rtc::RtcEngineVideoTrack videoTrack, int timeCost) override;
    void OnFirstAudioPacketSend(int timeCost) override;
    void OnFirstAudioPacketReceived(const char* uid, int timeCost) override;
    // void OnRenderRemoteVideoSizeChanged(const char* uid, ding::rtc::RtcEngineVideoTrack videoTrack, int newWidth, int newHeight, int oldWidth, int oldHeight) override;
    // void OnRenderLocalVideoSizeChanged(ding::rtc::RtcEngineVideoTrack videoTrack, int newWidth, int newHeight, int oldWidth, int oldHeight) override;
    void OnAudioSubscribeStateChanged(const char* uid, ding::rtc::RtcEngineSubscribeState oldState, ding::rtc::RtcEngineSubscribeState newState, int elapseSinceLastState, const char* channel) override;
    void OnVideoSubscribeStateChanged(const char* uid, ding::rtc::RtcEngineSubscribeState oldState, ding::rtc::RtcEngineSubscribeState newState, int elapseSinceLastState, const char* channel) override;
    // void OnScreenShareSubscribeStateChanged(const char* uid, ding::rtc::RtcEngineSubscribeState oldState, ding::rtc::RtcEngineSubscribeState newState, int elapseSinceLastState, const char* channel) override;
    // void OnSubscribeStreamTypeChanged(const char* uid, ding::rtc::RtcEngineVideoStreamType oldStreamType, ding::rtc::RtcEngineVideoStreamType newStreamType, int elapseSinceLastState, const char* channel) override;
    void OnRecordingDeviceAudioLevel(int level) override;
    // void OnPlayoutDeviceAudioLevel(int level) override;
    // void OnAudioVolumeIndication(const ding::rtc::AudioVolumeInfo* speakers, unsigned int speakerNumber) override;
    void OnAudioDeviceStateChanged(const char* deviceId, ding::rtc::RtcEngineDeviceType deviceType, ding::rtc::RtcEngineDeviceState deviceState) override;
    void OnVideoDeviceStateChanged(const char* deviceId, ding::rtc::RtcEngineDeviceType deviceType, ding::rtc::RtcEngineDeviceState deviceState) override;
    // void OnApiCalledExecuted(int error, const char* api, const char* result) override;
    // void OnSnapshotComplete(const char* userId, ding::rtc::RtcEngineVideoTrack videoTrack, const char* filePath, int width, int height, bool success) override;
    // void OnMediaExtensionMsgReceived(const char* uid, unsigned char* message, unsigned int size) override;
    // void OnAudioMixingStateChanged(const RtcEngineAudioMixingStatusConfig& status) override;
    // void OnListAllAudioGroups(const ding::rtc::StringArray& groups) override;
    // void OnAudioGroupJoinResult(int result, const ding::rtc::String& errMsg, const ding::rtc::String& group, RtcEngineAudioGroupMember* members, int memberCount) override;
    // void OnAudioGroupLeaveResult(int result, const ding::rtc::String& errMsg, const ding::rtc::String& group) override;
    // void OnAudioGroupDismissResult(int result, const ding::rtc::String& errMsg, const ding::rtc::String& group) override;
    // void OnAudioGroupMixResult(const ding::rtc::String& group, bool mix, int result, const ding::rtc::String& reason) override;
    // void OnAudioGroupMemberUpdate(int update_opt, const ding::rtc::String& group, RtcEngineAudioGroupMember* members, int memberCount) override;
    // void OnAudioGroupHallMembers(RtcEngineAudioGroupMember* hallMembers, int hallMemberCount) override;
    // void OnAudioGroupListUpdate(int update_opt, const ding::rtc::String& group) override;

private:
    QObject* service;

    // 特化版本，用于终止递归
    void appendParams(QVector<QVariant>& /*params*/) {}

    template<typename T, typename... Args>
    void appendParams(QVector<QVariant>& params, T&& first, Args&&... args) {
        // 如果是指针类型（如 const char*），转换为 QString 并加入 params
          if constexpr (std::is_pointer_v<std::remove_reference_t<T>>) {
              params.append(QString::fromUtf8(first ? first : "")); // 处理空指针
          } else {
              params.append(std::forward<T>(first)); // 普通类型直接加入
          }
          appendParams(params, std::forward<Args>(args)...); // 递归处理剩余参数
    }

    template<typename... Args>
    RTCEngineCallback t_packageCallback(AliRtcEvents::AliRtcCallbackEvent, Args... args);
};

